package com.panopset.gui;

import static com.panopset.Util.centerInScreen;
import static com.panopset.Util.x;

import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;

import javax.swing.JDialog;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;

import com.panopset.centralen.resource.Favicon;
import com.panopset.gui.container.PanCheckBox;

/**
 *
 * Typical Swing dialog box.
 *
 * @author Karl Dinwiddie
 *
 */
public class TypicalDialog {
    private final String title;
    private JDialog frame;
    private boolean remember = false;

    public enum DIALOG_FLAVOR {
        OK_ONLY, OK_CANCEL
    }

    public static void main(String... s) {
        dspdlg("Test", "Message\nnext line.");
    }

    /**
     * Display a message in a dialog box
     * @param title Frame title
     * @param msg Message to appear in a non-editable ScrollPane in the dialog box.
     */
    public static void dspdlg(String title, String msg) {
        TPanel cp = new TPanel.Builder().layout(new GridLayout(1,1)).construct();
        JTextArea ta = new JTextArea(msg);
        ta.setEditable(false);
        cp.add(new JScrollPane(ta));
        new TypicalDialog.Builder(title).centerPanel(cp).construct().getFrame().setVisible(true);
    }

    public boolean userCancelled = false;

    /**
     * Dialog width.
     */
    public static final int DIALOG_WIDTH = 600;

    /**
     * Dialog height.
     */
    public static final int DIALOG_HEIGHT = 300;

    public static final Dimension DIALOG_DIMENSIONS = new Dimension(
            DIALOG_WIDTH, DIALOG_HEIGHT);


    private TypicalDialog(String title) {
        this.title = title;
    }

    public JDialog getFrame() {
        if (frame == null) {
            frame = new JDialog();
            frame.setTitle(title);
            frame.setSize(DIALOG_DIMENSIONS);
            frame.setLocation(centerInScreen(DIALOG_DIMENSIONS));
            frame.setIconImage(Favicon.getLatest().getImageResource().getImage());
            frame.add(getPanel());
            frame.setModal(true);
            frame.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
            frame.getRootPane().setDefaultButton(getOkButton());
        }
        return frame;
    }

    protected void exit() {
        getFrame().dispose();
    }

    private JPanel panel;
    private TButton okButton;
    private TButton cancelButton;
    private PanCheckBox rememberCheckbox;

    public TButton getOkButton() {
        if (okButton == null) {
            okButton = new TButton();
            okButton.setText(x("OK"));
            okButton.setMnemonic(KeyEvent.VK_O);
            okButton.addActionListener(new ActionListener() {

                public void actionPerformed(ActionEvent e) {
                    exit();
                }

            });
        }
        return okButton;
    }

    public TButton getCancelButton() {
        if (cancelButton == null) {
            cancelButton = new TButton();
            cancelButton.setText(x("Cancel"));
            cancelButton.setMnemonic(KeyEvent.VK_C);
            cancelButton.addActionListener(new ActionListener() {

                public void actionPerformed(ActionEvent e) {
                    userCancelled = true;
                    exit();
                }

            });
        }
        return cancelButton;
    }

    public PanCheckBox getRememberCheckbox() {
        if (rememberCheckbox == null) {
            rememberCheckbox = new PanCheckBox(x("Remember password"),
                    x("Make sure you only do this on your own private computer, as the password will be stored unencrypted on your disk."));
        }
        return rememberCheckbox;
    }

    public JPanel getPanel() {
        if (panel == null) {
            panel = new JPanel();
        }
        return panel;
    }

    public static class Builder {
        private String title;
        private JPanel northPanel;
        private JPanel centerPanel;
        private Dimension size;
        private boolean remember = false;
        private DIALOG_FLAVOR dialogFlavor = DIALOG_FLAVOR.OK_ONLY;

        public Builder(String title) {
            this.title = title;
        }

        /**
         *
         * @param dialogFlavor
         *            default is OK_ONLY
         */
        public Builder dialogFlavor(DIALOG_FLAVOR dialogFlavor) {
            this.dialogFlavor = dialogFlavor;
            return this;
        }

        /**
         * Optional
         * @param size defaults to w=600h=300
         * @return
         */
        public Builder size(Dimension size) {
            this.size = size;
            return this;
        }

        public Builder northPanel(JPanel northPanel) {
            this.northPanel = northPanel;
            return this;
        }

        public Builder centerPanel(JPanel centerPanel) {
            this.centerPanel = centerPanel;
            return this;
        }

        public TypicalDialog construct() {
            TypicalDialog rtn = new TypicalDialog(title);
            rtn.remember = this.remember;
            rtn.getFrame().setLayout(new BorderLayout());
            if (northPanel != null) {
                rtn.getFrame().add(BorderLayout.CENTER, northPanel);
            }
            if (centerPanel != null) {
                rtn.getFrame().add(BorderLayout.CENTER, centerPanel);
            }
            if (size != null) {
                rtn.getFrame().setSize(size);
            }
            rtn.getFrame().add(BorderLayout.SOUTH, rtn.assembleControlPanel(this.dialogFlavor));
            return rtn;
        }

        public Builder remember() {
            remember = true;
            return this;
        }
    }

    Component assembleControlPanel(DIALOG_FLAVOR dialogFlavor) {
        TPanel controls = new TPanel.Builder().layout(new FlowLayout()).construct();
        switch (dialogFlavor) {
        case OK_CANCEL:
            controls.add(getCancelButton());
            controls.add(getOkButton());
            break;
        case OK_ONLY:
            controls.add(getOkButton());
            break;
        }
        if (remember) {
            controls.add(getRememberCheckbox().getPanel());
        }
        return controls;
    }

    public void display() {
        getFrame().setVisible(true);
    }
}
